﻿using LightCAD.Three.OpenGL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.Drawing.Actions
{
    public class ComponentInstance2dAction : ElementAction
    {
        public ComponentInstance2dAction():base() { }
        public ComponentInstance2dAction(IDocumentEditor docEditor) : base(docEditor)
        {

        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        {
            var cptIns = element as LcComponentInstance;
            var pen = this.GetDrawPen(element);
            var curves = cptIns?.Curves?.SelectMany(cs => cs.Curve2ds);
            if (curves == null)
            {
                return;
            }
            foreach (var curve in curves)
            {
                var points = curve.GetPoints(-1, this.vportRt.Viewport.Scale);
                for (int i = 0; i < points.Length; i++)
                {
                    var point = points[i];
                    point.ApplyMatrix3(matrix);
                }
                canvas.DrawPoints(SKPointMode.Polygon, points.Select(p => this.vportRt.ConvertWcsToScr(p).ToSKPoint()).ToArray(), pen);
            }
        }
        public override void Draw(SKCanvas canvas, LcElement element, Vector2 offset)
        {
            var cptIns = element as IComponentInstance;

            var pen = this.GetDrawPen(element);
            var curves = cptIns.Curves.SelectMany(cs => cs.Curve2ds);
            foreach (var curve in curves)
            {
                var points = curve.GetPoints(-1, this.vportRt.Viewport.Scale);
                for (int i = 0; i < points.Length; i++)
                {
                    var point = points[i];
                    point.Add(offset);
                }
                canvas.DrawPoints(SKPointMode.Polygon, points.Select(p => this.vportRt.ConvertWcsToScr(p).ToSKPoint()).ToArray(), pen);
            }
        }

        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var cpt = element as LcComponentInstance;
            return new ControlGrip[]
            {
                new ControlGrip
                {
                    Element = cpt,
                    Name = "Position",
                    Position = cpt.Position.ToVector2(),
                }
            };
        }

        private string _gripName;
        private Vector2 _position;
        private LcComponentInstance _cpt;

        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {
            var cpt = element as LcComponentInstance;
            _cpt = cpt;
            if (!isEnd)
            {
                _gripName = gripName;
                _position = position;
            }
            else
            {
                Vector2 dragpoint = position;

                if (this.vportRt.SnapRt?.Current != null)
                {
                    dragpoint = this.vportRt.SnapRt.Current.SnapPoint;
                }
                if (gripName == "Position")
                {
                    cpt.OnPropertyChangedBefore(nameof(cpt.Position), null, null);
                    cpt.Position.SetX(dragpoint.X);
                    cpt.Position.SetY(dragpoint.Y);
                    cpt.OnPropertyChangedAfter(nameof(cpt.Position), null, null);
                }
            }
        }

        public override void DrawDragGrip(SKCanvas canvas)
        {
            if (_cpt == null)
                return;
            
            if (_gripName == "Position")
            {
                var offset = _position - _cpt.Position.ToVector2();
                var curves = _cpt.Curves.SelectMany(cs => cs.Curve2ds);
                foreach (var curve in curves)
                {
                    var points = curve.GetPoints(-1, this.vportRt.Viewport.Scale);
                    for (int i = 0; i < points.Length; i++)
                    {
                        var point = points[i];
                        point.Add(offset);
                    }
                    canvas.DrawPoints(SKPointMode.Polygon, points.Select(p => this.vportRt.ConvertWcsToScr(p).ToSKPoint()).ToArray(), Constants.draggingPen);
                }
            }
        }
    }
}